///////////////////////////////////////////////////////////////////////////////
//
// DBT86 Project : x86 Platform : x86 Decode Tables
// Copyright (C) 2004 by Ben Hertzberg and Stanford University
// All Rights Reserved
//
// This code may not be used for any purpose without the express written
// consent of the author.  See the LICENSE.txt file for details.
//
//
// DESCRIPTION
//
// This unit implements various x86 decoding tables.
//
///////////////////////////////////////////////////////////////////////////////

#define INCL_INTERP_LOCALS
#include "interp.h"
#if CFG_CODEGEN
#include "codegen.h"
#endif

#if CFG_CODEGEN
#define OPDEF(a,b,c,d,e,f,g,h,i,j)     {b,c,&x86CodeGen::Gen##e##Op,d,GEN_##f,g,h,i,j},
#else
#define OPDEF(a,b,c,d,e,f,g,h,i,j)     {{b,c},d},
#endif

#define ModRM    X86_BITS_MODRM
#define Prefix   X86_BITS_INITIAL
#define SegCS    X86_BITS_PREFIX_SEGCS
#define SegDS    X86_BITS_PREFIX_SEGDS
#define SegES    X86_BITS_PREFIX_SEGES
#define SegFS    X86_BITS_PREFIX_SEGFS
#define SegGS    X86_BITS_PREFIX_SEGGS
#define SegSS    X86_BITS_PREFIX_SEGSS
#define Lock     X86_BITS_PREFIX_LOCK
#define Rep      X86_BITS_PREFIX_REP
#define RepNE    X86_BITS_PREFIX_REPNE
#define OpSz     X86_BITS_PREFIX_OPSIZE
#define AddrSz   X86_BITS_PREFIX_ADDRSIZE
#define Lockable X86_BITS_LOCKABLE
#define AllowRep X86_BITS_ALLOWREP
#define TwoByte  X86_BITS_TABLE2 | X86_BITS_INITIAL
#define Imm8     X86_BITS_IMM8
#define Imm8SX   X86_BITS_REL8
#define ImmV     X86_BITS_IMMV
#define Rel8     X86_BITS_REL8
#define RelV     X86_BITS_RELV
#define OfsV     X86_BITS_OFSV
#define ImmSeg   X86_BITS_IMMSEG
#define Imm16    X86_BITS_IMM16
#define Imm8XX   X86_BITS_IMM8_2
#define Group1a  X86_BITS_GROUP1A | X86_BITS_GROUP
#define Group1b  X86_BITS_GROUP1B | X86_BITS_GROUP
#define Group1c  X86_BITS_GROUP1C | X86_BITS_GROUP
#define Group2a  X86_BITS_GROUP2A | X86_BITS_GROUP
#define Group2b  X86_BITS_GROUP2B | X86_BITS_GROUP
#define Group2c  X86_BITS_GROUP2C | X86_BITS_GROUP
#define Group2d  X86_BITS_GROUP2D | X86_BITS_GROUP
#define Group2e  X86_BITS_GROUP2E | X86_BITS_GROUP
#define Group2f  X86_BITS_GROUP2F | X86_BITS_GROUP
#define Group3a  X86_BITS_GROUP3A | X86_BITS_GROUP
#define Group3b  X86_BITS_GROUP3B | X86_BITS_GROUP
#define Group4   X86_BITS_GROUP4 | X86_BITS_GROUP
#define Group5   X86_BITS_GROUP5 | X86_BITS_GROUP
#define Group6   X86_BITS_GROUP6 | X86_BITS_GROUP
#define Group7   X86_BITS_GROUP7 | X86_BITS_GROUP | X86_BITS_EXTGROUP
#define Group8   X86_BITS_GROUP8 | X86_BITS_GROUP
#define Group9   X86_BITS_GROUP9 | X86_BITS_GROUP | X86_BITS_EXTGROUP
#define Group10  X86_BITS_GROUP10 | X86_BITS_GROUP
#define Group11  X86_BITS_GROUP11 | X86_BITS_GROUP
#define Group12  X86_BITS_GROUP12 | X86_BITS_GROUP | X86_BITS_EXTGROUP
#define Group13  X86_BITS_GROUP13 | X86_BITS_GROUP | X86_BITS_EXTGROUP
#define Group14  X86_BITS_GROUP14 | X86_BITS_GROUP | X86_BITS_EXTGROUP
#define Group15  X86_BITS_GROUP15 | X86_BITS_GROUP | X86_BITS_EXTGROUP
#define Group16  X86_BITS_GROUP16 | X86_BITS_GROUP | X86_BITS_EXTGROUP
#define FPGroup  X86_BITS_TABLE_FP | X86_BITS_INITIAL | X86_BITS_FP
#define UNDEF    0
//
// These are the primary decode tables
//
x86DecodeEntry x86Table1[256] = {
#include "x86table1.inc"
};
x86DecodeEntry x86Table2[256] = {
#include "x86table2.inc"
};
//
// These are the extended decode tables for standard code
//
static x86DecodeEntry x86TableGrp1a[8] = {
#include "x86tableGrp1a.inc"
};
static x86DecodeEntry x86TableGrp1b[8] = {
#include "x86tableGrp1b.inc"
};
static x86DecodeEntry x86TableGrp1c[8] = {
#include "x86tableGrp1c.inc"
};
static x86DecodeEntry x86TableGrp2a[8] = {
#include "x86tableGrp2a.inc"
};
static x86DecodeEntry x86TableGrp2b[8] = {
#include "x86tableGrp2b.inc"
};
static x86DecodeEntry x86TableGrp2c[8] = {
#include "x86tableGrp2c.inc"
};
static x86DecodeEntry x86TableGrp2d[8] = {
#include "x86tableGrp2d.inc"
};
static x86DecodeEntry x86TableGrp2e[8] = {
#include "x86tableGrp2e.inc"
};
static x86DecodeEntry x86TableGrp2f[8] = {
#include "x86tableGrp2f.inc"
};
static x86DecodeEntry x86TableGrp3a[8] = {
#include "x86tableGrp3a.inc"
};
static x86DecodeEntry x86TableGrp3b[8] = {
#include "x86tableGrp3b.inc"
};
static x86DecodeEntry x86TableGrp4[8] = {
#include "x86tableGrp4.inc"
};
static x86DecodeEntry x86TableGrp5[8] = {
#include "x86tableGrp5.inc"
};
static x86DecodeEntry x86TableGrp6[8] = {
#include "x86tableGrp6.inc"
};
static x86DecodeEntry x86TableGrp7[16] = {
#include "x86tableGrp7.inc"
};
static x86DecodeEntry x86TableGrp8[8] = {
#include "x86tableGrp8.inc"
};
static x86DecodeEntry x86TableGrp9[16] = {
#include "x86tableGrp9.inc"
};
static x86DecodeEntry x86TableGrp10[8] = {
#include "x86tableGrp10.inc"
};
static x86DecodeEntry x86TableGrp11[8] = {
#include "x86tableGrp11.inc"
};
static x86DecodeEntry x86TableGrp12[16] = {
#include "x86tableGrp12.inc"
};
static x86DecodeEntry x86TableGrp13[16] = {
#include "x86tableGrp13.inc"
};
static x86DecodeEntry x86TableGrp14[16] = {
#include "x86tableGrp14.inc"
};
static x86DecodeEntry x86TableGrp15[16] = {
#include "x86tableGrp15.inc"
};
static x86DecodeEntry x86TableGrp16[16] = {
#include "x86tableGrp16.inc"
};

#if CFG_FPU
static x86DecodeEntry x86TableFPGrpD8a[8] = {
#include "x86tableFPGrpD8a.inc"
};
static x86DecodeEntry x86TableFPGrpD9a[8] = {
#include "x86tableFPGrpD9a.inc"
};
static x86DecodeEntry x86TableFPGrpDAa[8] = {
#include "x86tableFPGrpDAa.inc"
};
static x86DecodeEntry x86TableFPGrpDBa[8] = {
#include "x86tableFPGrpDBa.inc"
};
static x86DecodeEntry x86TableFPGrpDCa[8] = {
#include "x86tableFPGrpDCa.inc"
};
static x86DecodeEntry x86TableFPGrpDDa[8] = {
#include "x86tableFPGrpDDa.inc"
};
static x86DecodeEntry x86TableFPGrpDEa[8] = {
#include "x86tableFPGrpDEa.inc"
};
static x86DecodeEntry x86TableFPGrpDFa[8] = {
#include "x86tableFPGrpDFa.inc"
};
static x86DecodeEntry x86TableFPGrpD8b[64] = {
#include "x86tableFPGrpD8b.inc"
};
static x86DecodeEntry x86TableFPGrpD9b[64] = {
#include "x86tableFPGrpD9b.inc"
};
static x86DecodeEntry x86TableFPGrpDAb[64] = {
#include "x86tableFPGrpDAb.inc"
};
static x86DecodeEntry x86TableFPGrpDBb[64] = {
#include "x86tableFPGrpDBb.inc"
};
static x86DecodeEntry x86TableFPGrpDCb[64] = {
#include "x86tableFPGrpDCb.inc"
};
static x86DecodeEntry x86TableFPGrpDDb[64] = {
#include "x86tableFPGrpDDb.inc"
};
static x86DecodeEntry x86TableFPGrpDEb[64] = {
#include "x86tableFPGrpDEb.inc"
};
static x86DecodeEntry x86TableFPGrpDFb[64] = {
#include "x86tableFPGrpDFb.inc"
};
#endif

//
// This is the table of extended tables
//
x86DecodeEntry* x86TableGroup[] = {
  x86TableGrp1a,
  x86TableGrp1b,
  x86TableGrp1c,
  x86TableGrp2a,
  x86TableGrp2b,
  x86TableGrp2c,
  x86TableGrp2d,
  x86TableGrp2e,
  x86TableGrp2f,
  x86TableGrp3a,
  x86TableGrp3b,
  x86TableGrp4,
  x86TableGrp5,
  x86TableGrp6,
  x86TableGrp7,
  x86TableGrp8,
  x86TableGrp9,
  x86TableGrp10,
  x86TableGrp11,
  x86TableGrp12,
  x86TableGrp13,
  x86TableGrp14,
  x86TableGrp15,
  x86TableGrp16,
};

#if CFG_FPU
//
// This is the table of extended tables for FP code
//
x86DecodeEntry* x86TableFP[] = {
  x86TableFPGrpD8a,
  x86TableFPGrpD9a,
  x86TableFPGrpDAa,
  x86TableFPGrpDBa,
  x86TableFPGrpDCa,
  x86TableFPGrpDDa,
  x86TableFPGrpDEa,
  x86TableFPGrpDFa,
  x86TableFPGrpD8b,
  x86TableFPGrpD9b,
  x86TableFPGrpDAb,
  x86TableFPGrpDBb,
  x86TableFPGrpDCb,
  x86TableFPGrpDDb,
  x86TableFPGrpDEb,
  x86TableFPGrpDFb,
};
#endif

#undef OPDEF
#undef ModRM
#undef Prefix
#undef SegCS
#undef SegDS
#undef SegES
#undef SegFS
#undef SegGS
#undef SegSS
#undef Lock
#undef Rep
#undef RepNE
#undef OpSz
#undef AddrSz
#undef Lockable
#undef AllowRep
#undef TwoByte
#undef Imm8
#undef Imm8SX
#undef ImmV
#undef Rel8
#undef RelV
#undef OfsV
#undef ImmSeg
#undef Imm16
#undef Imm8XX
#undef Group1a
#undef Group1b
#undef Group1c
#undef Group2a
#undef Group2b
#undef Group2c
#undef Group2d
#undef Group2e
#undef Group2f
#undef Group3a
#undef Group3b
#undef Group4
#undef Group5
#undef Group6
#undef Group7
#undef Group8
#undef Group9
#undef Group10
#undef Group11
#undef Group12
#undef Group13
#undef Group14
#undef Group15
#undef Group16
#undef FPGroup
#undef UNDEF

// Table generation for Mod/RM and SIB decoding

ModRMEntry RM16Table[24] = {
#include "x86tableRM16.inc"
};

ModRMEntry RM32Table[24] = {
#include "x86tableRM32.inc"
};

SIBEntry SIBTable[256] = {
#include "x86tableSIB.inc"
};

